//
//  TTotheJsonModel.m
//  TaTogether
//
//  Created by 九月 on 8/21/24.
//

#import "TTotheJsonModel.h"

#import <objc/runtime.h>
#import "YYModel.h"


@interface TTotheJsonModel(){
    
    NSString *_urlString;
    Class _cls;
    NSMutableDictionary *_paras;
}

@end

@implementation TTotheJsonModel

static Class _myClassProperty;

+ (void)setMyClassProperty:(Class)value {
    _myClassProperty = value;
}

+ (Class)myClassProperty {
    return _myClassProperty;
}

-(void)initlize{
    
    _paras = [NSMutableDictionary dictionary];
    pageNo = 0;
    pageSize = 10;
    hasNextPage = YES;
}
+(instancetype)modelWithObserve:(id)observe{
    
    TTotheJsonModel *model = [[[self class] alloc] init];
    [model initlize];
    model->_observer = observe;
    [model loadCache];
    return model;
    
}

+(instancetype)modelWithObserve:(id)observe ext:(NSString *)cacheExt{
    
    TTotheJsonModel *model = [[[self class] alloc] init];
    [model initlize];
    model->_observer = self;
    model->_cacheExt = cacheExt;
    //model->_paras = [NSMutableDictionary dictionary];
    //加载缓存
    [model loadCache];
    return model;
}

#pragma mark ----- 网络请求
+(void)model_POST_Token:(NSString *)urlString paramtter:(NSDictionary *)paras result:(ModelBolck)resultBlock{
    //防止崩溃
    if(urlString == nil) {
        NSLog(@"---url错误");
      return;
    }
    
    
}
+(void)model_POST:(NSString *)urlString paramtter:(NSDictionary *)paras result:(ModelBolck)resultBlock{
    
    
    
}
+(void)model_GET:(NSString *)urlString paramtter:(NSDictionary *)paras result:(ModelBolck)resultBlock{
 
    
}

+(void)model_upload:(NSString *)urlString paramtter:(NSDictionary *)paras images:(NSArray *)images result:(ModelBolck)resultBlock{
    
    
    
     //图片上传
    
//    [WEINetworking uploadImagesWithUrl:API_UPLOAD(urlString) params:paras images:images success:^(id json) {
//        
//        id model = [[self class] mj_objectWithKeyValues:json];
//        resultBlock(model,nil);
//        
//    } failure:^(NSError *error) {
//        
//        resultBlock(nil,error.localizedDescription);
//        
//    }];

}

#pragma mark ------- block

//把URL ,参数 请求方式全部写在一起？？

//+(Class (^)(NSString *url,id paras, HttpsType type))URL{
//
//    return ^Class(NSString *url,id paras, HttpsType type){
//
//        return [self class];
//    };
//}

-(TTotheJsonModel*(^)(Class cls))CLS {
    return ^TTotheJsonModel*(Class cls){
        [[self class] setMyClassProperty:cls];
        return self;
    };
}

-(TTotheJsonModel*(^)(NSString *api))API {
    return ^TTotheJsonModel*(NSString *api){
        
        self->_api = api;
        return self;
    };
}

-(TTotheJsonModel*(^)(NSString *url))URL{
    
    return ^TTotheJsonModel*(NSString *url){
        
        self->_urlString = url;
        return self;
    };
}
-(TTotheJsonModel*(^)(id paras))PARA{
    
    return ^TTotheJsonModel*(id para){
        
        [self->_paras addEntriesFromDictionary:para];
        //_paras = [NSMutableDictionary dictionaryWithDictionary:para];
        return self;
    };
    
}
-(TTotheJsonModel*(^)(id paras))APPEND{
    
    return ^TTotheJsonModel*(id para){
        
        //if(!_paras) _paras = [NSMutableDictionary dictionary];
        [self->_paras addEntriesFromDictionary:para];
        return self;
    };
    
}
-(TTotheJsonModel*(^)(HttpsType))SEND{
    
    return ^(HttpsType type){
      
        //发送数据请求
        [self httpsSend:type];
        return self;
    };
    
}
-(NSDictionary *)parameters{
    
    return _paras;
}

-(void)httpsSend:(HttpsType)type{
    
    ModelBolck block = ^(id model ,NSString *error){
        
        //数据回调
        [self didFinishedLoad:model error:error];
    };
    
    switch (type) {
            
        case HttpTypeGet:
            [[self class] model_GET:_urlString paramtter:_paras result:block];
            break;
        case HttpTypePost:
            [[self class] model_POST_Token:_urlString paramtter:_paras result:block];
            break;
        case HttpTypePostByToken:
            
            break;
    }
}

#pragma mark ------JSMultipageDelegate
-(void)loadFirstPage {}
-(void)loadNextPage  {}
-(void)didFinishedLoad:(id)model error:(NSString *)error{
    
//    if (error) {
//
//        [SVProgressHUD showErrorWithStatus:error];
//
//    }else{
//
//
//    }
    if (!error) {
        
         [self copyDataToSelf:model];
    }else{
        
        NSLog(@"数据请求异常");
    }
    //数据回调
    [self sendSignal:model];
}






-(void)copyDataToSelf:(id)data{
    
    unsigned int propertyCount    = 0;
    objc_property_t *propertyList = class_copyPropertyList([self class], &propertyCount);
    
    for (int i=0; i<propertyCount; i++) {
        
        objc_property_t aProperty = propertyList[i];
        const char *name          = property_getName(aProperty);
        NSString *propertyName    = [NSString stringWithCString:name encoding:NSUTF8StringEncoding];
        id value = [data valueForKey:propertyName];
        
        if (value != nil) [self setValue:value forKey:propertyName];
        
        
    }
    free(propertyList);
    
}
void ESTIMATE(BOOL condition,Exception error,Exception sucess){
    
    condition ? (sucess ? sucess():nil):(error ? error():nil);
   
}

//这个方法不调用
//+(NSDictionary *)mj_objectClassInArray{
//
//    return [self matchObjectClass];
//
//}

+ (nullable NSDictionary<NSString *, id> *)modelContainerPropertyGenericClass{

    Class cls = [self myClassProperty];
    
    if (cls == nil) {
        return nil;
    } else {
        return @{@"data" : cls};
    }
}

#pragma mark ----------- 数据缓存
-(id)loadCache{
    
    id model = [NSKeyedUnarchiver unarchiveObjectWithFile:[self archieverPath]];
    if (model) {

        [self copyDataToSelf:model];
    }
    return model;
 //   return [NSKeyedUnarchiver unarchiveObjectWithFile:[self archieverPath]];
}

-(void)saveCache{
    
    [NSKeyedArchiver archiveRootObject:self toFile:[self archieverPath]];
}
-(void)deleteCache{
    
    [[NSFileManager defaultManager] removeItemAtPath:[self archieverPath] error:nil];
}
//-(NSString *)getFileSaveDate{
//
//    return nil;
//}
//归档路径
//帐号+类名+唯一标识
-(NSString *)archieverPath{
    
    //创建缓存路径文件夹
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSString *folderPath = [NSString stringWithFormat:@"%@/Documents/jsonCache",NSHomeDirectory()];
    if (![fileManager fileExistsAtPath:folderPath]) {
        
        [fileManager createDirectoryAtPath:folderPath withIntermediateDirectories:NO attributes:nil error:nil];
    }
    NSString *className = NSStringFromClass([self class]);
    NSString *account = @"account"; //model类 ---
    NSString *filePath = [NSString stringWithFormat:@"%@/%@-%@-m%@",folderPath,account,className,self->_cacheExt];
    NSLog(@"----%@",filePath);
    return filePath;
    
}
#pragma mark --------mode归档

-(id)initWithCoder:(NSCoder *)aDecoder{
    
    self = [super init];
    if (self) {
        
        [self modelCoder:aDecoder archieved:NO];
        
    }
    return self;
    
}

-(void)encodeWithCoder:(NSCoder *)aCoder{
    
    [self modelCoder:aCoder archieved:YES];
    
}

-(void)modelCoder:(NSCoder *)aCoder archieved:(BOOL)archiever{
    
    unsigned int propertyCount = 0;
    objc_property_t *propertys = class_copyPropertyList([self class], &propertyCount);
    for (int i=0; i<propertyCount; i++) {
        
        objc_property_t aProperty = propertys[i];
        NSString *propertyName = [NSString stringWithCString:property_getName(aProperty) encoding:NSUTF8StringEncoding];
        if (archiever) {
            
            id value = [self valueForKey:propertyName];
            [aCoder encodeObject:value forKey:propertyName];
            
        }else{
            
            id value = [aCoder decodeObjectForKey:propertyName];
            // NSLog(@"------value:%@",value);
            //value 为nil也可以???
            [self setValue:value forKey:propertyName];
        }
        
    }
    free(propertys);
    
    
}

#pragma mark ----------kvc空值处理

-(void)setNilValueForKey:(NSString *)key{
    
    NSLog(@"赋值为空:%@",key);
    
}
-(void)setValue:(id)value forUndefinedKey:(NSString *)key{
    
    NSLog(@"赋值失败--UndefinedKey:%@",key);
    
}
-(id)valueForUndefinedKey:(NSString *)key{
    
    NSLog(@"取值失败--UndefinedKey:%@",key);
    return nil;
}

@end



@implementation TTotheJsonModel(Signal)

-(void)sendSignal:(id)sender{
    
    NSString *selectName = [NSString stringWithFormat:@"message_%@_%@:",NSStringFromClass([_observer class]),NSStringFromClass([self class])];
    SEL selector= NSSelectorFromString(selectName);
    if (!_observer || !selector) return;
    if ([_observer respondsToSelector:selector]) {
       
        IMP imp = [_observer methodForSelector:selector];
        ImpFuncType func = (ImpFuncType)imp;
        func(_observer,selector,sender);
    }
    
    
    
}

@end
